/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fait.ferm.global;

import fait.ferm.engine.FermEngine;
import fait.ferm.engine.IfaceEngine;
import fait.ferm.engine.Plan;
import fait.ferm.engine.ResultEngine;
import fait.ferm.persists.Directory;
import fait.ferm.persists.Ferm;
import fait.ferm.persists.Game;
import fait.ferm.persists.SimpleDirItem;
import fait.ferm.persists.Users;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * Содержит глобальные объекты и методы приложения.
 * Такие как ссылка на главное окно, соединение с БД, интерфейс с движком
 * @author alex
 */
public class Glob {
    private static Connection con;
    /**
	 * Главное окно
	 */
	public static Stage primaryStage;
    /**
	 * Главное окно - панель диалога
	 */
	public static BorderPane dialogPane;
    /**
	 * Главное окно - панель диалога
	 */
	public static BorderPane dialogPane2;
	/**
	 * интерфейс с ядром
	 */
    private static IfaceEngine iFermEngine;
	/**
	 * текущий пользователь
	 */
    private static Users user;
	/**
	 * текущая игра
	 */
    private static Game game;
	/**
	 * текущая ферма
	 */
    private static Ferm ferm;
	/**
	 * текущий план
	 */
    private static Plan currentPlan;
	
	public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

	/**
	 * пустой элемент справочника
	 */
	public static final SimpleDirItem emptyDirItem = new SimpleDirItem(-1, "Не определено", "");
	/**
	 * текущий план
	 */
    private static HashMap<String, Directory> dirCache;
	
	public static final String[] cachedDirList={
		"cow_type",
		"credit_type",
		"equipment_type",
		"object_type",
		"pay_org",
		"resource_type",
		"skill",
		"sort",
		"supplies",
		"unit",
		"taxes_type"
	};
	
	/**
	 * мах 180 голов на ферме. 1 в год съедает 7300 к.е.(20 в день) итого максимум кормов 1 460 000 к.е.
	 */
	public static final int FODDER_MAX_QUANTITY = 1460000;
	
	/**
	 * Загружаем все мелкие справочники в глобальный кеш.
	 * Их список в массиве <code>cachedDirList</code>.
	 */
	public static void InitCachedDirs(){
		dirCache = new HashMap<>(cachedDirList.length);
		for(String tableName: cachedDirList){
			dirCache.put(tableName, new Directory(tableName));
		}		
	} 
	
	/**
	 * Проверяем, есть ли справочник в глобальном кеше.
	 * @return Если есть, то <code>true</code>.
	 */
	public static boolean hasDirInCache(String tableName){
		return dirCache.containsKey(tableName);
	}
	/**
	 * Возвращает справочник из глобального кеша. 
	 * @return Если нет в кеше, то <code>null</code>.
	 */
	public static Directory getDirInCache(String tableName){
		return dirCache.get(tableName);
	}
	/**
	 * Возвращает справочник из глобального кеша. 
	 * @return Если нет в кеше, то <code>null</code>.
	 */
	public static SimpleDirItem getObjInCache(String tableName, int id){
		Directory d = dirCache.get(tableName);
		if(d==null) return emptyDirItem;
		return d.get(id);
	}
	
	
	
	
	public static Users getUser(){ return user;}
	public static Ferm getFerm(){ return ferm;}
	public static Game getGame(){ 
		if(game!=null)return game;
		try (Statement st = con.createStatement()) {
			String q = "SELECT id FROM game WHERE user_id = " + user.getId();// + " ORDER BY name DSC";
			ResultSet rs = st.executeQuery(q);
			if(rs.next()){
				try {
					game = new Game(rs.getInt("id"));
				} catch (Exception ex) {
					Logger.getLogger(Glob.class.getName()).log(Level.SEVERE, null, ex);
				}
			}
			rs.close();
		}
		catch (SQLException ex) {
			Logger.getLogger(Glob.class.getName()).log(Level.SEVERE, null, ex);
		}		return game;

	}
	public static void setUser(Users u){user = u;}
	public static void setFerm() throws Exception{
		IfaceEngine iEngine = getFermEngine();
		if(user == null) throw new Exception("Попытка получения фермы без регистрации пользователя");
		ResultEngine res = iEngine.getFerm(user);
		try {
			ferm = res.getFerm();
		} catch (Exception ex) {
			Logger.getLogger(fait.ferm.FermMain.class.getName()).log(Level.SEVERE, null, ex);
			Platform.exit();
		}

	}
	/**
	 * 
	 * @return возвращает ссылку на текущий план
	 */
	public static Plan getPlan(){
		if(currentPlan == null) { currentPlan = new Plan();}
		return currentPlan;
	}
	/**
	 * 
	 * @return возвращает ссылку на интерфейс с движком
	 */
	public static IfaceEngine getFermEngine(){
		if(iFermEngine == null) { iFermEngine = new FermEngine();}
		return iFermEngine;
	}

    
    /**
	 * 
	 * @return возвращает соединение с БД. Путь к БД прописан в файле "config.txt" в папке с проектом, параметр "DBNAME"
	 */
	public static Connection getConnection(){
        if(con != null) {
			return con;
		}
        try {
            String dbName = null;
            BufferedReader br = null;
            //считываем имя базы из файла конфигурации
            try {
                 br = new BufferedReader(new FileReader("config.txt"));
                String buf;
                while( (buf = br.readLine()) != null){
                    if(buf.trim().toUpperCase().startsWith("DBNAME")){
                        String[] sa = buf.split("=");
                        dbName = sa[1].trim();
                    }
                }
            } catch (FileNotFoundException ex) {
                Logger.getLogger(Glob.class.getName()).log(Level.SEVERE, null, ex);
                Platform.exit();
            } catch (IOException ex) {
                Logger.getLogger(Glob.class.getName()).log(Level.SEVERE, null, ex);
                Platform.exit();
            } finally {
                try {
                    br.close();
                } catch (IOException ex) {
                    Logger.getLogger(Glob.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            //открываем соединение
            Class.forName("org.sqlite.JDBC");
            con = DriverManager.getConnection("jdbc:sqlite:"+dbName);
        } catch (SQLException ex) {
            Logger.getLogger(Glob.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Glob.class.getName()).log(Level.SEVERE, null, ex);
        }finally{ 
            return con;
        }
        
    }
    
}
